package no.sachmuld.methodcombination.demo;

import no.sachmuld.methodcombination.api.CrosscuttingBehaviour;
import no.sachmuld.methodcombination.api.MethodInvocation;
import org.apache.log4j.Logger;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;

/**
 *
 */
public class TransactionRollbackBehaviour extends CrosscuttingBehaviour {

    private static Logger logger = Logger.getLogger(TransactionRollbackBehaviour.class);

    private PlatformTransactionManager transactionManager;
    private TransactionDefinition transactionDefinition;

    public TransactionRollbackBehaviour(PlatformTransactionManager transactionManager) {
        this.transactionManager = transactionManager;
        this.transactionDefinition = createTransactionDefinition();
    }

    @Override
    public Object around(MethodInvocation<?> methodInvocation) {

        TransactionStatus status = transactionManager.getTransaction(transactionDefinition);
        logger.info("Transaction started");

        try {
            return methodInvocation.proceed();
        } finally {

            transactionManager.rollback(status);
            logger.info("Transaction rolled back");

        }
    }

    private TransactionDefinition createTransactionDefinition() {
        return new TransactionDefinition() {
            @Override
            public int getPropagationBehavior() {
                return PROPAGATION_REQUIRED;
            }

            @Override
            public int getIsolationLevel() {
                return ISOLATION_DEFAULT;
            }

            @Override
            public int getTimeout() {
                return TIMEOUT_DEFAULT;
            }

            @Override
            public boolean isReadOnly() {
                return false;
            }

            @Override
            public String getName() {
                return null;
            }
        };
    }
}
